

extern crate mongodb;
extern crate bson as bsonlib;
extern crate threadpool;
extern crate indicatif;
extern crate log;
extern crate colog;

extern crate colored; // not needed in Rust 2018
    

// use colored::*;
use colored::Colorize;
use super::text_read;
use indicatif::{ProgressBar,ProgressStyle};
// use threadpool::ThreadPool;
use std::sync::mpsc::Receiver;
use std::fs::create_dir;
use std::path::Path;
use String;
use serde::{Deserialize, Serialize};
// use log::error;

// use log::warn;

// Mongo used hear
// use mongodb::{bson, doc};
// use mongodb::coll::options::WriteModel;
// use mongodb::coll::Collection;
// use mongodb::{Client,ThreadedClient};
// use mongodb::db::ThreadedDatabase;
// use std::time::Instant;
// mongo used hear end
// fn text2bsons(coll: &Collection,datas: &Vec<text_read::Text>){
//     let mut count = 0;
//     let models = datas.iter().map(|t|{
//         count+=1;
//         println!("to model :{}", t) ;
//         WriteModel::InsertOne{
            
//             document: doc!{
//                 "id" => t.id.to_string(),
//                 "path" => t.path.to_string(), 
//                 "content" => t.content.to_string() 
//             }
//         }
        
//     }).collect();
//     println!("insert to {} : {}", coll.name(), count);
//     coll.bulk_write(models, true);
// }




#[derive(Serialize, Deserialize, Debug)]
struct Record {
    name : String,
    value : i64,
    info_type : String
}


pub fn observer_to_save(save_dir :&str, recive: Receiver<Result<text_read::Text, &'static str>>){
    // println!("tmp dir:{}", save_dir);
    let dir_path = Path::new(save_dir);
    if !dir_path.exists(){
        create_dir(dir_path).expect("can't crate dir .");
    }
    let mut finished_count = 0;
    let mut all_count = 0;
    let mut pb = ProgressBar::new(0);
    'save: loop {
        
        match recive.recv() {
            Ok(text_instance) =>{

                match text_instance{
                    Ok(t) =>{
                        // println!("{} -> ", t.get_no());
                        if t.id == "-1"{
                            // error!("{} deal failed | reason:{}\n", &t.path.red(), "error to deal with txt".blue() );
                            finished_count+= 1;
                            if all_count != 0{
                                pb.println(format!("{}/{}  {}", finished_count, all_count, t.path.red() ));
                            }
                            continue
                        }
                        match t.to_file(&dir_path){
                            Ok(_) => {
                                finished_count+= 1;
                                if all_count != 0{
                                    pb.set_position(finished_count);
                                    pb.println(format!("{}/{}  {}:{} {}", finished_count, all_count,&t.id, Path::new(&t.path).display(), text_read::get_now()));
                                }
                                // warn!("{}/{}  {}:{} {}", finished_count, all_count,&t.id, Path::new(&t.path).display(), text_read::get_now());
                                if finished_count == all_count{
                                    // error!("exit hear {} ", t.path);
                                    break 'save;
                                }
                            },
                            Err(e) => {
                                finished_count+= 1;
                                pb.println(format!("{} deal failed | reason:\n {}",&t.path.red(), e ));
                                // error!("{} deal failed | reason:{}\n", &t.path.red(), e );
                                // println!("to file {}",e);
                            }
                        }
                    },
                    Err(s) =>{
                        // error!("recv {} ", s.red());
                        all_count = s.to_string().parse::<i32>().unwrap() as u64;
                        pb = ProgressBar::new(all_count as u64);
                        pb.set_style(ProgressStyle::default_bar()
                            .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/files ({eta})")
                            .progress_chars("#>-"));
                        
                        // println!("------- check {} ok ------", all_count);
                        if all_count == 0 || all_count == finished_count{
                            break 'save;
                        }
                        // println!("wait all task finished!");
                    }
                };
                
            },
            Err(s) =>{
                all_count = s.to_string().parse::<i32>().unwrap() as u64;
                // println!("------- check {} ok ------", all_count);
                if all_count == 0 || all_count == finished_count{
                    break 'save;
                }
                // !("wait all task finished!");
                // break 'save;
            },
            
        }

    }
}

// pub fn observer_to_save_mongo(db :&str, collection: &str, recive: Receiver<Result<text_read::Text, &'static str>>){
//     let client = Client::connect("localhost", 27017).expect("Failed to initialize client.");
//     let db = client.db(db);
//     let coll = db.collection(collection);
//     let mut tmp_datas: Vec<text_read::Text> = vec![];
//     let mut start = Instant::now();

//     loop {
//         match recive.recv(){
//             Ok(text_instance) => {
//                 tmp_datas.push(text_instance.unwrap());
//                 if tmp_datas.len() > 100 {
//                     text2bsons(&coll, &tmp_datas);
//                     tmp_datas = vec![];
//                     start = Instant::now();
//                 }else if  start.elapsed().as_secs() > 10 &&  tmp_datas.len() > 0{
//                     text2bsons(&coll, &tmp_datas);
//                     tmp_datas = vec![];
//                     start = Instant::now();
//                 }
//                 // fun(text_instance);
//             },
//             Err(s) => {
//                 println!("exit with: {}", s);
//                 break;
//             },
//         }
//     }
// }
